home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / H.ZIP / RMACROS.H < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-10  |  16.4 KB  |  622 lines

  1. /*
  2.  *  Definitions for macros and manifest constants used in the compiler
  3.  *  interpreter.
  4.  */
  5.  
  6. /*
  7.  *  Definitions common to the compiler and interpreter.
  8.  */
  9.  
  10. /*
  11.  * Constants that are not likely to vary between implementations.
  12.  */
  13.  
  14. #define BitOffMask (IntBits-1)
  15. #define CsetSize (256/IntBits)    /* number of ints to hold 256 cset
  16.                  *  bits. Use (256/IntBits)+1 if
  17.                  *  256 % IntBits != 0 */
  18. #define MinListSlots        8    /* number of elements in an expansion
  19.                  * list element block  */
  20.  
  21. #define MaxCvtLen       257    /* largest string in conversions; the extra
  22.                  *  one is for a terminating null */
  23. #define MaxReadStr       512    /* largest string to read() in one piece */
  24. #define MaxIn          32767    /* largest number of bytes to read() at once */
  25. #define RandA        1103515245    /* random seed multiplier */
  26. #define RandC          453816694    /* random seed additive constant */
  27. #define RanScale 4.65661286e-10    /* random scale factor = 1/(2^31-1)) */
  28.  
  29. /*
  30.  * File status flags in status field of file blocks.
  31.  */
  32. #define Fs_Read         01    /* read access */
  33. #define Fs_Write     02    /* write access */
  34. #define Fs_Create     04    /* file created on open */
  35. #define Fs_Append    010    /* append mode */
  36. #define Fs_Pipe        020    /* reading/writing on a pipe */
  37.  
  38. #ifdef RecordIO
  39. #define Fs_Record       040     /* record structured file */
  40. #endif                    /* RecordIO */
  41.  
  42. #ifdef StandardLib
  43. #define Fs_Reading     0100     /* last file operation was read */
  44. #define Fs_Writing     0200     /* last file operation was write */
  45. #endif                    /* StandardLib */
  46.  
  47.  
  48. /*
  49.  * Codes returned by runtime support routines.
  50.  *  Note, some conversion routines also return type codes. Other routines may
  51.  *  return positive values other than return codes. sort() places restrictions
  52.  *  on Less, Equal, and Greater.
  53.  */
  54.  
  55. #define Less        -1
  56. #define Equal        0
  57. #define Greater        1
  58. #define CvtFail        -2
  59. #define Cvt        -3
  60. #define NoCvt        -4
  61. #define Failed        -5
  62. #define Defaulted    -6
  63. #define Succeeded        -7
  64. #define Error        -8
  65.  
  66. #undef ToAscii
  67. #undef FromAscii
  68. #if EBCDIC == 2
  69. #define ToAscii(e) (FromEBCDIC[e])
  70. #define FromAscii(e) (ToEBCDIC[e])
  71. #else                    /* EBCDIC == 2 */
  72. #define ToAscii(e) (e)
  73. #define FromAscii(e) (e)
  74. #endif                    /* EBCDIC == 2 */
  75.  
  76. /*
  77.  * Pointer to block.
  78.  */
  79. #define BlkLoc(d)    ((d).vword.bptr)
  80.  
  81. /*
  82.  * Check for null-valued descriptor.
  83.  */
  84. #define ChkNull(d)    ((d).dword==D_Null)
  85.  
  86. /*
  87.  * Check for equivalent descriptors.
  88.  */
  89. #define EqlDesc(d1,d2)    ((d1).dword == (d2).dword && BlkLoc(d1) == BlkLoc(d2))
  90.  
  91. /*
  92.  * Integer value.
  93.  */
  94. #define IntVal(d)    ((d).vword.integr)
  95.  
  96. /*
  97.  * Offset from top of block to value of variable.
  98.  */
  99. #define Offset(d)    ((d).dword & OffsetMask)
  100.  
  101. /*
  102.  * Check for pointer.
  103.  */
  104. #define Pointer(d)    ((d).dword & F_Ptr)
  105.  
  106. /*
  107.  * Check for qualifier.
  108.  */
  109. #define Qual(d)        (!((d).dword & F_Nqual))
  110.  
  111. /*
  112.  * Length of string.
  113.  */
  114. #define StrLen(q)    ((q).dword)
  115.  
  116. /*
  117.  * Location of first character of string.
  118.  */
  119. #define StrLoc(q)    ((q).vword.sptr)
  120. /*
  121.  * Type of descriptor.
  122.  */
  123. #define Type(d)        (int)((d).dword & TypeMask)
  124.  
  125. /*
  126.  * Check for variable.
  127.  */
  128. #define Var(d)        ((d).dword & F_Var)
  129.  
  130. /*
  131.  * Location of the value of a variable.
  132.  */
  133. #define VarLoc(d)    ((d).vword.descptr)
  134.  
  135. /*
  136.  *  Important note:  The code that follows is not strictly legal C.
  137.  *   It tests to see if pointer p2 is between p1 and p3. This may
  138.  *   involve the comparison of pointers in different arrays, which
  139.  *   is not well-defined.  The casts of these pointers to unsigned "words"
  140.  *   (longs or ints, depending) works with all C compilers and architectures
  141.  *   on which Icon has been implemented.  However, it is possible it will
  142.  *   not work on some system.  If it doesn't, there may be a "false
  143.  *   positive" test, which is likely to cause a memory violation or a
  144.  *   loop. It is not practical to implement Icon on a system on which this
  145.  *   happens.
  146.  */
  147.  
  148. #define InRange(p1,p2,p3) ((uword)(p2) >= (uword)(p1) && (uword)(p2) < (uword)(p3))
  149.  
  150. /*
  151.  * Get floating-point number from real block.
  152.  */
  153. #ifdef Double
  154. #define GetReal(dp,res)    { \
  155.                          word *rp, *rq; \
  156.                          rp = (word *) &(res); \
  157.                          rq = (word *) &(BlkLoc(*dp)->realblk.realval); \
  158.                          *rp++ = *rq++; \
  159.                          *rp = *rq;} 
  160. #else                    /* Double */
  161. #define GetReal(dp,res)    res = BlkLoc(*dp)->realblk.realval
  162. #endif                    /* Double */
  163.  
  164. /*
  165.  * Absolute value of x (word).
  166.  */
  167. #if SASC
  168. #define Abs(x) __builtin_abs(x)
  169. #else                    /* SASC */
  170. #define Abs(x) (((x) < 0) ? (-(x)) : (x))
  171. #endif                    /* SASC */
  172.  
  173. /*
  174.  * Maximum of x and y.
  175.  */
  176. #define Max(x,y)        ((x)>(y)?(x):(y))
  177. #if SASC
  178. #undef Max
  179. #define Max(x,y)     __builtin_max(x,y)
  180. #endif                    /* SASC */
  181.  
  182. /*
  183.  * Minimum of x and y.
  184.  */
  185. #define Min(x,y)        ((x)<(y)?(x):(y))
  186. #if SASC
  187. #undef Min
  188. #define Min(x,y)     __builtin_min(x,y)
  189. #endif                    /* SASC */
  190.  
  191. /*
  192.  * Some C compilers take '\n' and '\r' to be the same, so the
  193.  *  following definitions are used.
  194.  */
  195. #if EBCDIC
  196. /*
  197.  * Note that, in EBCDIC, "line feed" and "new line" are distinct
  198.  *  characters.  Icon's use of "line feed" is really "new line" in
  199.  *  C terms.
  200.  */
  201. #define LineFeed '\n' /* if really "line feed", that's 37 */
  202. #define CarriageReturn '\r'
  203. #else                    /* EBCDIC */
  204. #define LineFeed  10
  205. #define CarriageReturn 13
  206. #endif                    /* EBCDIC */
  207.  
  208. /*
  209.  * Construct an integer descriptor.
  210.  */
  211. #define MakeInt(i,dp)    { \
  212.                       (dp)->dword = D_Integer; \
  213.                          IntVal(*dp) = (word)(i);}
  214.  
  215. /*
  216.  * Offset in word of cset bit.
  217.  */
  218. #define CsetOff(b)    ((b) & BitOffMask) 
  219. /*
  220.  * Set bit b in cset c.
  221.  */
  222. #define Setb(b,c)    (*CsetPtr(b,c) |= (01 << CsetOff(b))) 
  223. /*
  224.  * Test bit b in cset c.
  225.  */
  226. #define Testb(b,c)    ((*CsetPtr(b,c) >> CsetOff(b)) & 01) 
  227.  
  228. /*
  229.  * Check whether a set or table needs resizing.
  230.  */
  231. #define SP(p) ((struct b_set *)p)
  232. #define TooCrowded(p) \
  233.    ((SP(p)->size > MaxHLoad*(SP(p)->mask+1)) && (SP(p)->hdir[HSegs-1] == NULL))
  234. #define TooSparse(p) \
  235.    ((SP(p)->hdir[1] != NULL) && (SP(p)->size < MinHLoad*(SP(p)->mask+1)))
  236. /*
  237.  * Definitions and declarations used for storage management.
  238.  */
  239.  
  240. #define F_Mark        0100000     /* bit for marking blocks */
  241.  
  242. #define Static  1            /* collection is for static region */
  243. #define Strings    2            /* collection is for strings */
  244. #define Blocks    3            /* collection is for blocks */
  245.  
  246. /*
  247.  * Get type of block pointed at by x.
  248.  */
  249. #define BlkType(x)   (*(word *)x)
  250.  
  251. /*
  252.  * BlkSize(x) takes the block pointed to by x and if the size of
  253.  *  the block as indicated by bsizes[] is nonzero it returns the
  254.  *  indicated size; otherwise it returns the second word in the
  255.  *  block contains the size.
  256.  */
  257. #define BlkSize(x) (bsizes[*(word *)x & ~F_Mark] ? \
  258.              bsizes[*(word *)x & ~F_Mark] : *((word *)x + 1))
  259.  
  260.  
  261. /*
  262.  * Type codes (descriptors and blocks).
  263.  */
  264. #define T_String    -1    /* string -- for reference; not used */
  265. #define T_Null         0    /* null value */
  266. #define T_Integer     1    /* integer */
  267.  
  268. #ifdef LargeInts
  269. #define T_Lrgint     2    /* long integer */
  270. #endif                    /* LargeInts */
  271.  
  272. #define T_Real         3    /* real number */
  273. #define T_Cset         4    /* cset */
  274. #define T_File         5    /* file */
  275. #define T_Proc         6    /* procedure */
  276. #define T_Record     7    /* record */
  277. #define T_List         8    /* list header */
  278. #define T_Lelem         9    /* list element */
  279. #define T_Set        10    /* set header */
  280. #define T_Selem        11    /* set element */
  281. #define T_Table        12    /* table header */
  282. #define T_Telem        13    /* table element */
  283. #define T_Tvtbl        14    /* table element trapped variable */
  284. #define T_Slots        15    /* set/table hash slots */
  285. #define T_Tvsubs    16    /* substring trapped variable */
  286. #define T_Refresh    17    /* refresh block */
  287. #define T_Coexpr    18    /* co-expression */
  288. #define T_External    19    /* external block */
  289. #define T_Kywdint    20    /* integer keyword */
  290. #define T_Kywdpos    21    /* keyword &pos */
  291. #define T_Kywdsubj    22    /* keyword &subject */
  292.  
  293. #define MaxType        23    /* maximum type number */
  294.  
  295. /*
  296.  * Definitions for keywords.
  297.  */
  298.  
  299. #define k_pos kywd_pos.vword.integr    /* value of &pos */
  300. #define k_random kywd_ran.vword.integr    /* value of &random */
  301. #define k_trace kywd_trc.vword.integr    /* value of &trace */
  302.  
  303. /*
  304.  * Descriptor types and flags.
  305.  */
  306.  
  307. #define D_Null        (T_Null     | D_Typecode)
  308. #define D_Integer    (T_Integer  | D_Typecode)
  309.  
  310. #ifdef LargeInts
  311. #define D_Lrgint    (T_Lrgint | D_Typecode | F_Ptr)
  312. #endif                    /* LargeInts */
  313.  
  314. #define D_Real        (T_Real     | D_Typecode | F_Ptr)
  315. #define D_Cset        (T_Cset     | D_Typecode | F_Ptr)
  316. #define D_File        (T_File     | D_Typecode | F_Ptr)
  317. #define D_Proc        (T_Proc     | D_Typecode | F_Ptr)
  318. #define D_List        (T_List     | D_Typecode | F_Ptr)
  319. #define D_Lelem        (T_Lelem    | D_Typecode | F_Ptr)
  320. #define D_Table        (T_Table    | D_Typecode | F_Ptr)
  321. #define D_Telem        (T_Telem    | D_Typecode | F_Ptr)
  322. #define D_Set        (T_Set      | D_Typecode | F_Ptr)
  323. #define D_Selem        (T_Selem    | D_Typecode | F_Ptr)
  324. #define D_Record    (T_Record   | D_Typecode | F_Ptr)
  325. #define D_Tvsubs    (T_Tvsubs   | D_Typecode | F_Ptr | F_Var)
  326. #define D_Tvtbl        (T_Tvtbl    | D_Typecode | F_Ptr | F_Var)
  327. #define D_Kywdint    (T_Kywdint  | D_Typecode | F_Ptr | F_Var)
  328. #define D_Kywdpos    (T_Kywdpos  | D_Typecode | F_Ptr | F_Var)
  329. #define D_Kywdsubj    (T_Kywdsubj | D_Typecode | F_Ptr | F_Var)
  330. #define D_Refresh    (T_Refresh  | D_Typecode | F_Ptr)
  331. #define D_Coexpr    (T_Coexpr   | D_Typecode | F_Ptr)
  332. #define D_External    (T_External | D_Typecode | F_Ptr)
  333. #define D_Slots        (T_Slots    | D_Typecode | F_Ptr)
  334.  
  335. #define D_Var        (F_Var | F_Nqual | F_Ptr)
  336. #define D_Typecode    (F_Nqual | F_Typecode)
  337.  
  338. #define TypeMask    63    /* type mask */
  339. #define OffsetMask    (~(D_Var)) /* offset mask for variables */
  340.  
  341. /*
  342.  * "In place" dereferencing.
  343.  */
  344. #define Deref(d) if (Var(d)) deref(&d, &d)
  345.  
  346. /*
  347.  * Construct a substring trapped variable.
  348.  */
  349. #define SubStr(dest,var,len,pos)\
  350.    if ((var)->dword == D_Tvsubs)\
  351.       (dest)->vword.bptr = (union block *)alcsubs(len, (pos) +\
  352.          BlkLoc(*(var))->tvsubs.sspos - 1, &BlkLoc(*(var))->tvsubs.ssvar);\
  353.    else\
  354.       (dest)->vword.bptr = (union block *)alcsubs(len, pos, (var));\
  355.    (dest)->dword = D_Tvsubs;
  356.  
  357. /*
  358.  * Find debug struct in procedure frame, assuming debugging is enabled.
  359.  *  Note that there is always one descriptor in array even if it is not
  360.  *  being used.
  361.  */
  362. #define PFDebug(pf) ((struct debug *)((char *)(pf).tend.d +\
  363.     sizeof(struct descrip) * ((pf).tend.num ? (pf).tend.num : 1)))
  364.  
  365. /*
  366.  * Macro for initialized procedure block.
  367.  */
  368. #define B_IProc(n) struct {word title; word blksize; int (*ccode)();\
  369.    word nparam; word ndynam; word nstatic; word fstatic;\
  370.    struct sdescrip quals[n];} 
  371.  
  372. #ifdef MultiRegion
  373. #define ssize    (curstring->size)
  374. #define strbase  (curstring->base)
  375. #define strend   (curstring->end)
  376. #define strfree  (curstring->free)
  377.  
  378. #define abrsize  (curblock->size)
  379. #define blkbase  (curblock->base)
  380. #define blkend   (curblock->end)
  381. #define blkfree  (curblock->free)
  382. #endif                    /* MultiRegion */
  383.  
  384. #if COMPILER
  385.  
  386. #define Poll()
  387.  
  388. #else                    /* COMPILER */
  389.  
  390. /*
  391.  * Definitions for the interpreter.
  392.  */
  393.  
  394.  
  395. /*
  396.  * Codes returned by invoke to indicate action.
  397.  */
  398. #define I_Builtin    201    /* A built-in routine is to be invoked */
  399. #define I_Fail        202    /* goal-directed evaluation failed */
  400. #define I_Continue    203    /* Continue execution in the interp loop */
  401. #define I_Vararg    204    /* A function with a variable number of args */
  402.  
  403. /*
  404.  * Generator types.
  405.  */
  406. #define G_Csusp        1
  407. #define G_Esusp        2
  408. #define G_Psusp        3
  409.  
  410.  
  411. /*
  412.  * Evaluation stack overflow margin
  413.  */
  414.  
  415. #define PerilDelta 100
  416.  
  417. /*
  418.  * Macro definitions related to descriptors.
  419.  */
  420.  
  421. /*
  422.  * The following code is operating-system dependent [@rt.01].  Define
  423.  *  PushAval for computers that store longs and pointers differently.
  424.  */
  425.  
  426. #if PORT
  427. #define PushAVal(x) PushVal(x)
  428. Deliberate Syntax Error
  429. #endif                    /* PORT */
  430.  
  431. #if AMIGA || ARM || ATARI_ST || MACINTOSH || MVS || UNIX || VM || VMS
  432. #define PushAVal(x) PushVal(x)
  433. #endif                    /* AMIGA || ARM || ATARI_ST ... */
  434.  
  435. #if MSDOS || OS2
  436. #if HIGHC_386 || ZTC_386 || INTEL_386
  437. #define PushAVal(x) PushVal(x)
  438. #else                    /* HIGHC_386 || ZTC_386 || INTEL_386 */
  439. static union {
  440.        pointer stkadr;
  441.        word stkint;
  442.    } stkword;
  443.  
  444. #define PushAVal(x)  {sp++; \
  445.             stkword.stkadr = (char *)(x); \
  446.             *sp = stkword.stkint;}
  447. #endif                    /* HIGHC_386 || ZTC_386 || INTEL_386 */
  448. #endif                    /* MSDOS || OS2 */
  449.  
  450. /*
  451.  * End of operating-system specific code.
  452.  */
  453.  
  454. /*
  455.  * Macros for pushing values on the interpreter stack.
  456.  */
  457.  
  458. /*
  459.  * Push descriptor.
  460.  */
  461. #define PushDesc(d)    {*++sp = ((d).dword); sp++;*sp =((d).vword.integr);}
  462.  
  463. /*
  464.  * Push null-valued descriptor.
  465.  */
  466. #define PushNull    {*++sp = D_Null; sp++; *sp = 0;}
  467.  
  468. /*
  469.  * Push word.
  470.  */
  471. #define PushVal(v)    {*++sp = (word)(v);}
  472.  
  473. /*
  474.  * Macros related to function and operator definition.
  475.  */
  476.  
  477. /*
  478.  * Procedure block for a function.
  479.  */
  480.  
  481.  
  482. #define FncBlock(f,nargs,deref) \
  483.     struct b_iproc Cat(B,f) = {\
  484.     T_Proc,\
  485.     Vsizeof(struct b_proc),\
  486.     Cat(X,f),\
  487.     nargs,\
  488.     -1,\
  489.     deref, 0,\
  490.     {sizeof(Lit(f))-1,Lit(f)}};
  491.  
  492.  
  493. /*
  494.  * Function declaration for variable number of arguments.
  495.  */
  496. #define FncDcl(nm,n) FncBlock(nm,n,0) Cat(X,nm)(cargp)  register dptr cargp;
  497.  
  498. /*
  499.  * Function declaration for variable number of arguments.
  500.  */
  501. #define FncDclV(nm) FncBlock(nm,-1,0) Cat(X,nm)(nargs,cargp) int nargs; register dptr cargp;
  502.  
  503. /*
  504.  * Function declaration without dereferenced arguments.
  505.  */
  506. #define FncNDcl(nm,n) FncBlock(nm,n,-1) Cat(X,nm)(cargp)  register dptr cargp;
  507.  
  508. /*
  509.  * Function declaration for variable number of arguments.
  510.  */
  511. #define FncNDclV(nm) FncBlock(nm,-1,-1) Cat(X,nm)(nargs,cargp) int nargs; register dptr cargp;
  512.  
  513. /*
  514.  * Procedure block for an operator.
  515.  */
  516. #define OpBlock(f,nargs,sname,xtrargs)\
  517.     struct b_iproc Cat(B,f) = {\
  518.     T_Proc,\
  519.     Vsizeof(struct b_proc),\
  520.     Cat(O,f),\
  521.     nargs,\
  522.     -1,\
  523.     xtrargs,\
  524.     0,\
  525.     {sizeof(sname)-1,sname}};
  526.  
  527. /*
  528.  * Operator declaration.
  529.  */
  530. #define OpDcl(nm,n,pn) OpBlock(nm,n,pn,0) Cat(O,nm)(cargp) register dptr cargp;
  531.  
  532. /*
  533.  * Operator declaration with extra working argument.
  534.  */
  535. #define OpDclE(nm,n,pn) OpBlock(nm,-n,pn,0) Cat(O,nm)(cargp) register dptr cargp;
  536.  
  537. /*
  538.  * Agent routine declaration.
  539.  */
  540. #define AgtDcl(nm) Cat(A,nm)(cargp) register dptr cargp;
  541.  
  542. /*
  543.  * Macros to access Icon arguments in C functions.
  544.  */
  545.  
  546. /*
  547.  * n-th argument.
  548.  */
  549. #define Arg(n)         (cargp[n])
  550.  
  551. /*
  552.  * Type field of n-th argument.
  553.  */
  554. #define ArgType(n)    (cargp[n].dword)
  555.  
  556. /*
  557.  * Value field of n-th argument.
  558.  */
  559. #define ArgVal(n)    (cargp[n].vword.integr)
  560.  
  561. /*
  562.  * Specific arguments.
  563.  */
  564. #define Arg0    (cargp[0])
  565. #define Arg1    (cargp[1])
  566. #define Arg2    (cargp[2])
  567. #define Arg3    (cargp[3])
  568. #define Arg4    (cargp[4])
  569. #define Arg5    (cargp[5])
  570. #define Arg6    (cargp[6])
  571. #define Arg7    (cargp[7])
  572. #define Arg8    (cargp[8])
  573.  
  574. /* Suspend has been eliminated.  I dare not axe the Xver. */
  575.  
  576. /* Forward is no more. This is an Xfer placeholder */
  577.  
  578. /*
  579.  * Miscellaneous macro definitions.
  580.  */
  581.  
  582.  
  583. #define StackBase(ce) BlkLoc(ce)
  584. #endif                    /* COMPILER */
  585. /*
  586.  * Constants controlling expression evaluation.
  587.  */
  588. #if COMPILER
  589. #define A_Resume    -1    /* expression failed: resume a generator */
  590. #define A_Continue      -2    /* expression returned: continue execution */
  591. #define A_FallThru      -3      /* body function: fell through end of code */
  592. #define A_Coact        1    /* co-expression ativation */
  593. #define A_Coret        2    /* co-expression return */
  594. #define A_Cofail    3    /* co-expression failure */
  595. #else                    /* COMPILER */
  596. #define A_Resume    1        /* routine failed */
  597. #define A_Pret_uw    2        /* interp unwind for Op_Pret */
  598. #define A_Unmark_uw    3        /* interp unwind for Op_Unmark */
  599. #define A_Pfail_uw    4        /* interp unwind for Op_Pfail */
  600. #define A_Lsusp_uw    5        /* interp unwind for Op_Lsusp */
  601. #define A_Eret_uw    6        /* interp unwind for Op_Eret */
  602. #define A_Continue    7        /* routine returned */
  603. #define A_Coact        8        /* co-expression activated */
  604. #define A_Coret        9        /* co-expression returned */
  605. #define A_Cofail    10        /* co-expression failed */
  606. #endif                    /* COMPILER */
  607.  
  608. /*
  609.  * Address of word containing cset bit b (c is a struct descrip of type Cset).
  610.  */
  611. #define CsetPtr(b,c)    (BlkLoc(c)->cset.bits + (((b)&0377) >> LogIntBits)) 
  612.  
  613. #if MSDOS
  614. #if (MICROSOFT && defined(M_I86HM)) || (TURBO && defined(__HUGE__))
  615. #define ptr2word(x) ((uword)((char huge *)x - (char huge *)zptr))
  616. #define word2ptr(x) ((char huge *)((char huge *)zptr + (uword)x))
  617. #else                    /* MICROSOFT ... */
  618. #define ptr2word(x) (uword)x
  619. #define word2ptr(x) ((char *)x)
  620. #endif                    /* MICROSOFT ... */
  621. #endif                    /* MSDOS */
  622.